package com.qianyu.core.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qianyu.core.entity.base.BaseIdDto;
import com.qianyu.core.entity.bean.User;
import com.qianyu.core.entity.dto.UserDTO;
import com.qianyu.core.enumerate.DataStatusEnum;
import com.qianyu.core.enumerate.ResultEnum;
import com.qianyu.core.exception.CustomerException;
import com.qianyu.core.helper.LoginHelper;
import com.qianyu.core.mapper.UserMapper;
import com.qianyu.core.service.UserService;
import com.qianyu.core.util.MD5Util;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Override
    public User loginFront(UserDTO.UserLoginDTO dto) {
        User user = baseMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, dto.getUsername())
                .eq(User::getPassword, MD5Util.md5(dto.getPassword())).lt(User::getRole,2));
        if (ObjectUtils.isEmpty(user)) {
            throw new CustomerException(ResultEnum.USER_IDENTITY_VERIFICATION_FAILED);
        }
        if (user.getDeleteStatus().equals(DataStatusEnum.DISABLE.getVal())) {
            throw new CustomerException(ResultEnum.USER_ACCOUNT_IS_FROZEN);
        }
        LoginHelper.login(user, false);
        user.setToken(StpUtil.getTokenValue());
        return user;
    }

    @Override
    public User loginBack(UserDTO.UserLoginDTO dto) {
        User user = baseMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, dto.getUsername())
                .eq(User::getPassword, MD5Util.md5(dto.getPassword())).eq(User::getRole,2));
        if (ObjectUtils.isEmpty(user)) {
            throw new CustomerException(ResultEnum.USER_IDENTITY_VERIFICATION_FAILED);
        }
        if (user.getDeleteStatus().equals(DataStatusEnum.DISABLE.getVal())) {
            throw new CustomerException(ResultEnum.USER_ACCOUNT_IS_FROZEN);
        }
        LoginHelper.login(user, false);
        user.setToken(StpUtil.getTokenValue());
        return user;
    }

    /**
     * 注册普通用户
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean registerUser(UserDTO.UserRegisterDTO dto) {
        if(!dto.getPassword().equals(dto.getPasswordTwo())){
            throw new CustomerException(ResultEnum.PASSWORD_VERIFICATION_FAILED);
        }
        validatedUser(dto.getUsername(),0);
        User user = new User();
        BeanUtils.copyProperties(dto, user);
        user.setNickname(dto.getUsername());
        user.setRole(0);
        return save(user);
    }

    /**
     * 添加代理
     * @param dto
     * @return
     */

    @Override
    public boolean registerUser(UserDTO.UserSaveDTO dto) {
        validatedUser(dto.getUsername(),1);
        User user = new User();
        BeanUtils.copyProperties(dto, user);
        user.setRole(1);
        return save(user);
    }

    private void validatedUser(String username, int i) {
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(User::getUsername,username).eq(User::getRole,i);
        User user = baseMapper.selectOne(wrapper);
        if(ObjectUtil.isNotEmpty(user)){
            throw new CustomerException(ResultEnum.USER_LOGIN_NAME_HAS_EXIST);
        }
    }

    @Override
    public boolean changeUserInfo(UserDTO.UserUpdateDto dto) {
        LambdaUpdateWrapper<User> wrapper = Wrappers.<User>lambdaUpdate();
        if (!StringUtils.isEmpty(dto.getNickname())) {
            wrapper.set(User::getNickname, dto.getNickname());
        }
        if (!StringUtils.isEmpty(dto.getUsername())) {

            if(!dto.getUsername().matches(".*[^\\u4e00-\\u9fa5].*")){
                throw new CustomerException(ResultEnum.USERNAME_NOT_MATCH);
            }
            wrapper.set(User::getUsername, dto.getUsername());
        }
        if (!StringUtils.isEmpty(dto.getRemark())) {
            wrapper.set(User::getRemark, dto.getRemark());
        }
        if (!ObjectUtils.isEmpty(dto.getMoney())) {
            wrapper.set(User::getMoney, dto.getMoney());
        }
        if (!ObjectUtils.isEmpty(dto.getRecycleRatio())) {
            wrapper.set(User::getRecycleRatio, dto.getRecycleRatio());
        }
        if (!ObjectUtils.isEmpty(dto.getDayRent())) {
            wrapper.set(User::getDayRent, dto.getDayRent());
        }
        if (dto.getStatus() != null) {
            wrapper.set(User::getDeleteStatus, dto.getStatus());
        }
        wrapper.eq(User::getId, dto.getId());
        return update(wrapper);
    }

    /**
     * 修改用户信息
     *
     * @param dto
     */
    @Override
    public boolean changeUserInfoByFront(UserDTO.UserUpdateDto dto) {
        LambdaUpdateWrapper<User> wrapper = Wrappers.<User>lambdaUpdate();
        if (!StringUtils.isEmpty(dto.getNickname())) {
            wrapper.set(User::getNickname, dto.getNickname());
        }
        if (!StringUtils.isEmpty(dto.getUsername())) {
            wrapper.set(User::getUsername, dto.getUsername());
        }
        if (!StringUtils.isEmpty(dto.getRemark())) {
            wrapper.set(User::getRemark, dto.getRemark());
        }
        wrapper.eq(User::getId, dto.getId());
        return update(wrapper);
    }

    @Override
    public User getInfo(BaseIdDto idDTO) {
        return baseMapper.selectById(idDTO.getId());
    }

    @Override
    public Page<User> pageListUser(UserDTO.UserPageDTO dto) {
        List<User> users = list();
        Map<Long, String> map = users.stream().collect(Collectors.toMap(User::getId, User::getNickname));
        Page<User> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
        wrapper.like(!ObjectUtils.isEmpty(dto.getUsername()), User::getUsername, dto.getUsername())
                .or().like(!ObjectUtils.isEmpty(dto.getUsername()), User::getNickname, dto.getUsername())
                .lt(User::getRole, 2);
        IPage<User> userIPage = baseMapper.selectPage(page, wrapper);
        userIPage.getRecords().forEach(u -> u.setAgencyName(map.get(u.getId())));
        return (Page<User>) userIPage;
    }

    @Override
    public boolean changePassword(UserDTO.PasswordDto dto) {
        User user = getById(dto.getId());

        if(!user.getPassword().equals(MD5Util.md5(dto.getOdlPassword()))){
            throw new CustomerException(ResultEnum.PASSWORD_IS_NOT_SUCCESS);
        }

//        if (!MD5Util.md5(dto.getOdlPassword()).equals(user.getPassword())) {
//            throw new CustomerException(ResultEnum.PASSWORD_VERIFICATION_FAILED);
//        }

        user.setPassword(MD5Util.md5(dto.getNewPassword()));
        return updateById(user);
    }

    @Override
    public List<UserDTO.UserSimpleDTO> getUsers() {
        return BeanUtil.copyToList(list(Wrappers.<User>lambdaQuery()
                .eq(User::getAgencyId, LoginHelper.getUserId())
                .eq(User::getDeleteStatus, DataStatusEnum.ISABLE.getVal()))
                , UserDTO.UserSimpleDTO.class);
    }
}
